package kassiopeia.agent.infrastructure;

import kassiopeia.agent.io.EventMessage;
import kassiopeia.agent.io.MessageSender;
import kassiopeia.agent.seda.SEDA;
import kassiopeia.plugin.Event;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class EventRouter {

    private static final Logger logger = Logger.getLogger(EventRouter.class);

    @Autowired
    private SEDA seda;

    @Autowired
    private MessageSender messageSender;

    @Value("${kassiopeia.agent.id}")
    private String thisAgentId;

    @Autowired
    private EventDistributionService distributionService;

    public void routeEvent(Event event, String pluginInstanceId, String pluginOutputId) {
        String targetAgentId = distributionService.findResponsibleAgent(event);

        if(targetAgentId.equals(thisAgentId)) {
            routeEventLocally(event, pluginInstanceId, pluginOutputId);
        } else {
            logger.debug("Routing event: " + event + " to another agent: " + targetAgentId);

            EventMessage message = new EventMessage(thisAgentId, pluginInstanceId, pluginOutputId, event);
            messageSender.send(message, targetAgentId);
        }
    }

    public void routeEventLocally(Event event, String pluginInstanceId, String pluginOutputId) {
        logger.debug("Routing event locally");
        seda.send(pluginInstanceId, pluginOutputId, event);
    }

    public SEDA getSeda() {
        return seda;
    }

    public void setSeda(SEDA seda) {
        this.seda = seda;
    }

    public MessageSender getMessageSender() {
        return messageSender;
    }

    public void setMessageSender(MessageSender messageSender) {
        this.messageSender = messageSender;
    }

    public String getThisAgentId() {
        return thisAgentId;
    }

    public void setThisAgentId(String thisAgentId) {
        this.thisAgentId = thisAgentId;
    }

    public EventDistributionService getDistributionService() {
        return distributionService;
    }

    public void setDistributionService(EventDistributionService distributionService) {
        this.distributionService = distributionService;
    }
}
